package openbang.account.web.portal.client;


import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class CropImg implements EntryPoint {
    //图片固有属性
	private TextBox actionSizeTxt = null;
	private TextBox cropSizeTxt = null;
	//当图片路径为本地路径时，IE能显示图片, FireFox不能显示图片
	private Hidden imgUrl = null;
	private TextBox imgSizeTxt = null;//原始像素大小
	private TextBox resizeRateTxt = null;

	//图片修改属性
	private Button resizeSmall = null;
	private Button resizeOrgi = null;
	private Button resizeBig = null;

	private TextBox imgNowSizeTxt = null;
	//裁剪框左上角  基于操作区的坐标
	private TextBox cropXYTxt = null; 
	
	
	//中间属性值
	//private float resizeVal = 0.0f; //当前缩放的比例值	
	private float resizeRate = 0.05f;//单击一次按钮缩放的比例值。	
	private int orgiWidth = 0;//原图宽度
	private int orgiHeight = 0;//原图高度
	private int actionWidth = 0;//操作区宽度
	private int actionHeight = 0;//操作区高度
	private int cropWidth = 0;//操作区宽度
	private int cropHeight = 0;//操作区高度
	
	//绝对DIV里,图片操作区域.  里面放置图片Image和剪裁框
	AbsolutePanel absolutePanel = new AbsolutePanel();
	
	//图片  可以缩放,但不能小于裁剪框 ---OK
	//如果当前大小超过操作区域,可以拖动(即控制显示图片的某方形区域位置)---暂不实现
	//问题：在移动裁剪框时,图片容易被置为选择中的效果，导致鼠标松开后,裁剪框得不到事件 
	Image img = new Image(); 
	
	//剪裁框  只能在 Image大小的范围内拖动。不能缩放。当图片缩小时,剪裁框也跟着缩小移动的范围
	//private HTML cropBox = new HTML("<table border=1 width=\"100%\" height=\"100%\"><tr><td></td></tr></table>");
	//需要样式 cropBoxDiv
	private HTML cropBox = new HTML("<table border=1 width=\"100%\" height=\"100%\"><tr><td></td></tr></table>");//cropBox本身就是一个<div></div>
	//private Grid cropBox = new Grid();
    private boolean dragging;
    private int dragStartX=0, dragStartY=0; //鼠标开始拖动的位置（相对的是裁剪框的左上角的坐标）
    private int cropBoxX=0, cropBoxY=0;     //裁剪框在操作区的坐标
    private int newCropBoxX=0, newCropBoxY=0;     //裁剪框在操作区移动过程中的坐标
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		//进行UI绑定 
		actionSizeTxt = TextBox.wrap(Document.get().getElementById("actionSizeTxt"));		
		cropSizeTxt = TextBox.wrap(Document.get().getElementById("cropSizeTxt"));
		imgSizeTxt = TextBox.wrap(Document.get().getElementById("imgSizeTxt"));		
		imgUrl = Hidden.wrap(Document.get().getElementById("imgUrl"));
		resizeRateTxt = TextBox.wrap(Document.get().getElementById("resizeRateTxt"));
		//fileUrl = FileUpload.wrap(Document.get().getElementById("fileUrl"));

		resizeSmall = Button.wrap(Document.get().getElementById("resize_small"));
		resizeOrgi = Button.wrap(Document.get().getElementById("resize_orgi"));
		resizeBig = Button.wrap(Document.get().getElementById("resize_big"));
		
		imgNowSizeTxt = TextBox.wrap(Document.get().getElementById("imgNowSizeTxt"));		
		cropXYTxt = TextBox.wrap(Document.get().getElementById("cropXYTxt"));		
		
		RootPanel.get("img_action_div").add(absolutePanel);
		absolutePanel.setTitle("图片操作区");
		absolutePanel.add(img);
		absolutePanel.setWidgetPosition(img, 0, 0);
		img.addLoadHandler(new LoadHandler(){
			public void onLoad(LoadEvent event) {
				//存储图片的实际大小  --- 
				orgiWidth = img.getWidth();
				orgiHeight = img.getHeight();
				imgSizeTxt.setValue(""+orgiWidth+"*"+orgiHeight);
				//Window.alert("orgiWidth="+orgiWidth+",orgiHeight="+orgiHeight);
			}
		});
		img.addErrorHandler(new ErrorHandler(){
			public void onError(ErrorEvent event) {
				Window.alert("Error: load imgage for url="+imgUrl.getValue());
			}
		});
		
		
		//裁剪框
		//DOM.setStyleAttribute(cropBox.getElement(), "border", "1px"); IE6里，只能在边框线上能捕获鼠标. why?
		cropBox.setStyleName("cropBoxDiv");
		cropBox.setTitle("裁剪框,鼠标按下可以移动");
		absolutePanel.add(cropBox);
		MouseHandler cropBoxMouseHandler = new MouseHandler();
		cropBox.addMouseDownHandler(cropBoxMouseHandler);
		cropBox.addMouseMoveHandler(cropBoxMouseHandler);
		cropBox.addMouseOutHandler(cropBoxMouseHandler);
		cropBox.addMouseOverHandler(cropBoxMouseHandler);
		cropBox.addMouseUpHandler(cropBoxMouseHandler);
		//cropBox.addMouseWheelHandler(handler);滚轮?
		//事件控制
		resizeOrgi.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				resizeImg(0);
			}
		});
		resizeSmall.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				resizeImg(-1);
			}
		});
		resizeBig.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				resizeImg(1);
			}
		});
		
		//初始化数据
		initData();
	}
	
	/**
	 * 根据一些参数初始图片操作区
	 * 当界面上修改了一些参数，重新调用该方法
	 */
	public void initData(){
		//图片操作区域最大显示的宽高
		if(actionSizeTxt.getValue()==null || "".equals(actionSizeTxt.getValue())){
			actionSizeTxt.setValue("500*500");
		}
		String[] actionSizeArray = actionSizeTxt.getValue().split("\\*");
		actionWidth = Integer.parseInt(actionSizeArray[0]);
		actionHeight = Integer.parseInt(actionSizeArray[1]);
		absolutePanel.setPixelSize(actionWidth,actionHeight);
		if(imgUrl.getValue()==null || "".equals(imgUrl.getValue())){
			Window.alert("没有设置图片路径,请设置后刷新");
			return;
		}
		img.setUrl(imgUrl.getValue());		
		//缩放比例尺
		if(resizeRateTxt.getValue()!=null && !"".equals(resizeRateTxt.getValue())){
			resizeRate = (float)(Integer.parseInt(resizeRateTxt.getValue())*1.0/100);
		}
		//裁剪框的宽高
		String[] cropSizeArray = cropSizeTxt.getValue().split("\\*");
		cropWidth = Integer.parseInt(cropSizeArray[0]);
		cropHeight = Integer.parseInt(cropSizeArray[1]);
		cropBox.setPixelSize(cropWidth,cropHeight);
		//让裁剪框在操作区居中
		cropBoxX = (actionWidth-cropWidth)/2;
		cropBoxY =  (actionHeight-cropHeight)/2;
		absolutePanel.setWidgetPosition(cropBox,cropBoxX,cropBoxY);
		//文本框的一些缺省值
		imgNowSizeTxt.setValue(""+img.getWidth()+"*"+img.getHeight());
		cropXYTxt.setValue(""+cropBoxX+","+cropBoxY);
	}
	
	/**
	 * 缩放图片
	 * 当前图片的宽或高小于裁剪框时,不能再缩小
	 * @param resizeDirect  方向  -1 表示缩小, 1 表示放大 0 表示还原实际大小
	 */
	public void resizeImg(int resizeDirect){
		//计算新的宽高
		int newW = img.getWidth();
		int newH = img.getHeight();
		if(resizeDirect==0){
			newW =orgiWidth;
			newH =orgiHeight;
		}
		else if(resizeDirect==-1){
			if(newW<=cropWidth || newH <=cropHeight){
				Window.alert("不能再缩小");
				return;
			}
			newW = (int)(newW*1.0 - resizeRate*orgiWidth);
			newH = (int)(newH*1.0 - resizeRate*orgiHeight);
		}
		else {
			newW = (int)(newW*1.0 + resizeRate*orgiWidth);
			newH = (int)(newH*1.0 + resizeRate*orgiHeight);
		}
		img.setPixelSize(newW,newH);
		imgNowSizeTxt.setValue(""+newW+"*"+newH);
	}
	
	/**
	 * 计算裁剪框可以移动的范围。
	 * 一般当图片缩小时要重新计算
	 * 能移动的范围为：
	 * 1.当图片大小超过操作区，则只能在操作区里移动
	 * 2.当图片大小不超过操作区，则只能在图片范围内移动
	 */
	private void calcuVlidaRect(){
		
	}
	
	protected void beginDragging(MouseDownEvent event) {
		//if(!dragging){
		    dragging = true;
		    DOM.setCapture(cropBox.getElement());
		    dragStartX = event.getX();
		    dragStartY = event.getY();
		    newCropBoxX = cropBoxX;
		    newCropBoxY = cropBoxY;
		//}
	}	
	
	protected void continueDragging(MouseMoveEvent event) {
		if (dragging) {
		   //计算裁剪框新的左上角位置（基于操作区）
		   newCropBoxX = cropBoxX + ( event.getX()- dragStartX);   
		   newCropBoxY = cropBoxY + ( event.getY()- dragStartY);
		   newCropBoxX = newCropBoxX<0?0:newCropBoxX;
		   newCropBoxY = newCropBoxY<0?0:newCropBoxY;
		   newCropBoxX = newCropBoxX+cropWidth>actionWidth?actionWidth-cropWidth:newCropBoxX;
		   newCropBoxY = newCropBoxY+cropHeight>actionHeight?actionHeight-cropHeight:newCropBoxY;
		   cropXYTxt.setValue(""+newCropBoxX+","+newCropBoxY);		   
		   absolutePanel.setWidgetPosition(cropBox, newCropBoxX, newCropBoxY);		    	  
		}
	}
	protected void endDragging(MouseUpEvent event) {
		//if (dragging) {
			  dragging = false;				
			  DOM.releaseCapture(cropBox.getElement());
			  cropBoxX = newCropBoxX;
			  cropBoxY = newCropBoxY;
		//}
    }
	
	private class MouseHandler implements MouseDownHandler, MouseUpHandler,
      MouseOutHandler, MouseOverHandler, MouseMoveHandler {
        //鼠标按下 
	    public void onMouseDown(MouseDownEvent event) {
	      beginDragging(event);
	      //cropBox.addStyleName("cropBoxCursorMove");
	    }
	    //鼠标移动
	    public void onMouseMove(MouseMoveEvent event) {
	      continueDragging(event);
	    }
	
	    //鼠标移出裁剪框
	    public void onMouseOut(MouseOutEvent event) {
	       //GWT.log("onMouseOut x="+event.getX()+",y="+event.getY(),null);
	    	cropBox.removeStyleName("cropBoxCursorIn");
	    }
	    //鼠标经过、进入裁剪框
	    public void onMouseOver(MouseOverEvent event) {
		   //GWT.log("MouseOverEvent x="+event.getX()+",y="+event.getY(),null);
	       cropBox.addStyleName("cropBoxCursorIn");
	    }
	    //鼠标松开
	    public void onMouseUp(MouseUpEvent event) {
	      endDragging(event);	      
	      //cropBox.removeStyleName("cropBoxCursorMove");
	    }
	  }
	
}
